package com.lineage.server.model.Instance;

import com.lineage.config.ConfigOther;
import com.lineage.data.executor.NpcExecutor;
import com.lineage.server.datatables.DeShopChatTable;
import com.lineage.server.datatables.NpcChatTable;
import com.lineage.server.datatables.NpcTable;
import com.lineage.server.datatables.lock.SpawnBossReading;
import com.lineage.server.model.L1AttackNpc;
import com.lineage.server.model.L1Character;
import com.lineage.server.model.L1GroundInventory;
import com.lineage.server.model.L1HateList;
import com.lineage.server.model.L1Inventory;
import com.lineage.server.model.L1Location;
import com.lineage.server.model.L1Magic;
import com.lineage.server.model.L1MobGroupInfo;
import com.lineage.server.model.L1MobSkillUse;
import com.lineage.server.model.L1NpcChatTimer;
import com.lineage.server.model.L1Object;
import com.lineage.server.model.L1Spawn;
import com.lineage.server.model.L1Teleport;
import com.lineage.server.model.map.L1Map;
import com.lineage.server.model.map.L1WorldMap;
import com.lineage.server.model.skill.L1SkillUse;
import com.lineage.server.serverpackets.S_ChangeShape;
import com.lineage.server.serverpackets.S_DoActionGFX;
import com.lineage.server.serverpackets.S_NPCPack;
import com.lineage.server.serverpackets.S_NewMaster;
import com.lineage.server.serverpackets.S_RemoveObject;
import com.lineage.server.serverpackets.S_Resurrection;
import com.lineage.server.serverpackets.S_ServerMessage;
import com.lineage.server.serverpackets.S_SkillHaste;
import com.lineage.server.serverpackets.S_SkillSound;
import com.lineage.server.serverpackets.ServerBasePacket;
import com.lineage.server.templates.L1Npc;
import com.lineage.server.templates.L1NpcChat;
import com.lineage.server.timecontroller.npc.NpcWorkTimer;
import com.lineage.server.timecontroller.quest.KIRTAS_Timer;
import com.lineage.server.types.Point;
import com.lineage.server.world.World;
import com.lineage.server.world.WorldNpc;
import com.lineage.server.world.WorldQuest;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class L1NpcInstance extends L1Character {
  public static final int MOVE_SPEED = 0;
  
  public static final int ATTACK_SPEED = 1;
  
  public static final int MAGIC_SPEED = 2;
  
  public static final int HIDDEN_STATUS_NONE = 0;
  
  public static final int HIDDEN_STATUS_SINK = 1;
  
  public static final int HIDDEN_STATUS_FLY = 2;
  
  public static final int HIDDEN_STATUS_ICE = 3;
  
  public static final int HIDDEN_STATUS_KIRTAS = 4;
  
  public static final int REST_MILLISEC = 10;
  
  public static final int DISTANCE = 20;
  
  public static final int CHAT_TIMING_APPEARANCE = 0;
  
  public static final int CHAT_TIMING_DEAD = 1;
  
  public static final int CHAT_TIMING_HIDE = 2;
  
  public static final int CHAT_TIMING_GAME_TIME = 3;
  
  public static final int USEITEM_HEAL = 0;
  
  public static final int USEITEM_HASTE = 1;
  
  private static final Log _log = LogFactory.getLog(L1NpcInstance.class);
  
  private static final long serialVersionUID = 1L;
  
  private static final Random _random = new Random();
  
  public static int[] healPotions = new int[] { 40012, 40011, 40010 };
  
  public static int[] haestPotions = new int[] { 140018, 40018, 140013, 40013 };
  
  protected final L1HateList _hateList;
  
  protected final L1HateList _dropHateList;
  
  protected final List<L1ItemInstance> _targetItemList;
  
  private final HashMap<L1ItemInstance, DelItemTime> _del_map;
  
  public L1Inventory _inventory;
  
  public L1MobSkillUse _mobSkill;
  
  public NpcExecutor TALK;
  
  public NpcExecutor ACTION;
  
  public NpcExecutor ATTACK;
  
  public NpcExecutor DEATH;
  
  public NpcExecutor WORK;
  
  public NpcExecutor SPAWN;
  
  public boolean _destroyed;
  
  public int _barrierTime;
  
  protected boolean ISASCAPE;
  
  protected L1Character _target;
  
  protected L1ItemInstance _targetItem;
  
  protected L1Character _master;
  
  protected boolean _hprRunning;
  
  protected NpcMoveExecutor _npcMove;
  
  private L1Npc _npcTemplate;
  
  private L1Spawn _spawn;
  
  private int _spawnNumber;
  
  private int _petcost;
  
  private boolean firstFound;
  
  private int _randomMoveDistance;
  
  private int _randomMoveDirection;
  
  private boolean _aiRunning;
  
  private boolean _actived;
  
  private boolean _firstAttack;
  
  private int _sleep_time;
  
  private boolean _deathProcessing;
  
  private boolean _mprRunning;
  
  private int _passispeed;
  
  private int _atkspeed;
  
  private boolean _pickupItem;
  
  private String _nameId;
  
  private boolean _Agro;
  
  private boolean _Agrocoi;
  
  private boolean _Agrososc;
  
  private int _homeX;
  
  private int _homeY;
  
  private boolean _reSpawn;
  
  private int _lightSize;
  
  private boolean _weaponBreaked;
  
  private int _hiddenStatus;
  
  private int _movementDistance;
  
  private int _tempLawful;
  
  private int _drainedMana;
  
  private boolean _rest;
  
  private boolean _isResurrect;
  
  private L1MobGroupInfo _mobGroupInfo;
  
  private int _mobGroupId;
  
  private int _bowActId;
  
  private int _ranged;
  
  private int _skyTime;
  
  private int _quest_id;
  
  private boolean _isShop;
  
  private int _spawnTime;
  
  private boolean _isspawnTime;
  
  private boolean _isremovearmor;
  
  private int _deadTimerTemp;
  
  private int _stop_time;
  
  private int _work_time;
  
  private KIRTAS_Timer _kirtastimer;
  
  private long _shells_damag_time;
  
  private long _shells_silence_time;
  
  private String _craftkey;
  
  public L1NpcInstance(L1Npc template) {
    this._inventory = new L1Inventory();
    this.firstFound = true;
    this._randomMoveDistance = 0;
    this._randomMoveDirection = 0;
    this.TALK = null;
    this.ACTION = null;
    this.ATTACK = null;
    this.DEATH = null;
    this.WORK = null;
    this.SPAWN = null;
    this.ISASCAPE = false;
    this._aiRunning = false;
    this._actived = false;
    this._firstAttack = false;
    this._hateList = new L1HateList();
    this._dropHateList = new L1HateList();
    this._targetItemList = new ArrayList<>();
    this._del_map = new HashMap<>();
    this._target = null;
    this._targetItem = null;
    this._master = null;
    this._deathProcessing = false;
    this._hprRunning = false;
    this._mprRunning = false;
    this._npcMove = null;
    this._movementDistance = 0;
    this._tempLawful = 0;
    this._drainedMana = 0;
    this._destroyed = false;
    this._rest = false;
    this._isResurrect = false;
    this._mobGroupInfo = null;
    this._mobGroupId = 0;
    this._bowActId = -1;
    this._ranged = -1;
    this._isShop = false;
    this._spawnTime = 0;
    this._isspawnTime = false;
    this._isremovearmor = false;
    this._deadTimerTemp = -1;
    this._stop_time = -1;
    this._work_time = -1;
    this._shells_damag_time = 0L;
    this._shells_silence_time = 0L;
    this._craftkey = null;
    setStatus(0);
    setMoveSpeed(0);
    setDead(false);
    setStatus(0);
    setreSpawn(false);
    this._npcMove = new NpcMove(this);
    if (template != null)
      setting_template(template); 
  }
  
  public static void shuffle(L1Object[] arr) {
    int i = arr.length - 1;
    while (i > 0) {
      int t = (int)(Math.random() * i);
      L1Object tmp = arr[i];
      arr[i] = arr[t];
      arr[t] = tmp;
      i--;
    } 
  }
  
  public static int checkObject(int x, int y, short m, int d) {
    L1Map map = L1WorldMap.get().getMap(m);
    switch (d) {
      case 1:
        if (map.isPassable(x, y, 1))
          return 1; 
        if (map.isPassable(x, y, 0))
          return 0; 
        if (map.isPassable(x, y, 2))
          return 2; 
        break;
      case 2:
        if (map.isPassable(x, y, 2))
          return 2; 
        if (map.isPassable(x, y, 1))
          return 1; 
        if (map.isPassable(x, y, 3))
          return 3; 
        break;
      case 3:
        if (map.isPassable(x, y, 3))
          return 3; 
        if (map.isPassable(x, y, 2))
          return 2; 
        if (map.isPassable(x, y, 4))
          return 4; 
        break;
      case 4:
        if (map.isPassable(x, y, 4))
          return 4; 
        if (map.isPassable(x, y, 3))
          return 3; 
        if (map.isPassable(x, y, 5))
          return 5; 
        break;
      case 5:
        if (map.isPassable(x, y, 5))
          return 5; 
        if (map.isPassable(x, y, 4))
          return 4; 
        if (map.isPassable(x, y, 6))
          return 6; 
        break;
      case 6:
        if (map.isPassable(x, y, 6))
          return 6; 
        if (map.isPassable(x, y, 5))
          return 5; 
        if (map.isPassable(x, y, 7))
          return 7; 
        break;
      case 7:
        if (map.isPassable(x, y, 7))
          return 7; 
        if (map.isPassable(x, y, 6))
          return 6; 
        if (map.isPassable(x, y, 0))
          return 0; 
        break;
      case 0:
        if (map.isPassable(x, y, 0))
          return 0; 
        if (map.isPassable(x, y, 7))
          return 7; 
        if (map.isPassable(x, y, 1))
          return 1; 
        break;
    } 
    return -1;
  }
  
  protected void startAI() {
    if (isAiRunning())
      return; 
    if (isDead())
      return; 
    if (destroyed())
      return; 
    if (getCurrentHp() <= 0)
      return; 
    NpcAI npcai = new NpcAI(this);
    setAiRunning(true);
    npcai.startAI();
    startHpRegeneration();
    startMpRegeneration();
  }
  
  public void onItemUse() {}
  
  public void searchTarget() {}
  
  public void addMaster(L1PcInstance master) {
    try {
      StringBuilder stringBuilder = new StringBuilder();
      if (master != null) {
        if (master.get_other().get_color() != 0)
          stringBuilder.append(master.get_other().color()); 
        if (master.isProtector()) {
          stringBuilder.append("**守护者**");
        } else {
          stringBuilder.append(master.getViewName());
        } 
      } else {
        stringBuilder.append("");
      } 
      master.sendPackets((ServerBasePacket)new S_NewMaster(stringBuilder.toString(), this));
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
  }
  
  public void checkTarget() {
    if (!isAiRunning())
      startAI(); 
    try {
      if (getNpcTemplate().is_boss() && 
        CheckMaxMovementDistance())
        return; 
      if (this._target == null) {
        clearTagert();
        return;
      } 
      if (this._target.getMapId() != getMapId()) {
        clearTagert();
        return;
      } 
      if (this._target.getCurrentHp() <= 0) {
        clearTagert();
        return;
      } 
      if (this._target.isDead()) {
        clearTagert();
        return;
      } 
      if (get_showId() != this._target.get_showId()) {
        clearTagert();
        return;
      } 
      if (this._target.isInvisble() && !getNpcTemplate().is_agrocoi() && 
        !this._hateList.containsKey(this._target)) {
        clearTagert();
        return;
      } 
      int distance = getLocation().getTileDistance((Point)this._target.getLocation());
      if (distance > 30) {
        clearTagert();
        return;
      } 
    } catch (Exception e) {
      return;
    } 
  }
  
  public boolean CheckMaxMovementDistance() {
    L1NpcInstance npc = this;
    if (npc.getMovementDistance() > 0 && 
      getLocation().getLineDistance(new Point(npc.getHomeX(), npc.getHomeY())) > 
      npc.getMovementDistance()) {
      clearTagert();
      npc.teleport(npc.getHomeX(), npc.getHomeY(), getHeading());
      return true;
    } 
    return false;
  }
  
  private void clearTagert() {
    if (this._target != null)
      tagertClear(); 
    if (!this._hateList.isEmpty()) {
      this._target = this._hateList.getMaxHateCharacter();
      checkTarget();
    } 
  }
  
  public boolean isHate(L1Character cha) {
    return this._hateList.isHate(cha);
  }
  
  public void setHate(L1Character cha, int hate) {
    try {
      if (cha != null && cha.getId() != getId()) {
        if (!isFirstAttack() && hate != 0) {
          hate += getMaxHp() / 10;
          setFirstAttack(true);
        } 
        if (this._npcMove != null)
          this._npcMove.clear(); 
        this._hateList.add(cha, hate);
        this._dropHateList.add(cha, hate);
        this._target = this._hateList.getMaxHateCharacter();
        checkTarget();
      } 
      if (!isAiRunning())
        startAI(); 
    } catch (Exception e) {
      return;
    } 
  }
  
  public void setLink(L1Character cha) {}
  
  public void serchLink(L1PcInstance targetPlayer, int family) {
    List<L1Object> targetKnownObjects = targetPlayer.getKnownObjects();
    Iterator<L1Object> iterator = targetKnownObjects.iterator();
    while (iterator.hasNext()) {
      Object knownObject = iterator.next();
      if (knownObject instanceof L1NpcInstance) {
        L1NpcInstance npc = (L1NpcInstance)knownObject;
        if (get_showId() != npc.get_showId())
          continue; 
        if (npc.getNpcTemplate().get_agrofamily() > 0)
          if (npc.getNpcTemplate().get_agrofamily() == 1) {
            if (npc.getNpcTemplate().get_family() == family)
              npc.setLink(targetPlayer); 
          } else {
            npc.setLink(targetPlayer);
          }  
        L1MobGroupInfo mobGroupInfo = getMobGroupInfo();
        if (mobGroupInfo == null || getMobGroupId() == 0 || getMobGroupId() != npc.getMobGroupId())
          continue; 
        if (npc.getNpcId() == 99007)
          return; 
        npc.setLink(targetPlayer);
      } 
    } 
  }
  
  public void onTarget() {
    try {
      switch (getNpcId()) {
        case 99030:
        case 99083:
        case 107037:
          Astarothfire();
          break;
      } 
      setActived(true);
      if (this._targetItemList.size() > 0)
        this._targetItemList.clear(); 
      if (this._targetItem != null)
        this._targetItem = null; 
      L1Character target = this._target;
      if (target == null) {
        tagertClear();
        return;
      } 
      if (getAtkspeed() == 0 && getPassispeed() > 0 && getLevel() <= 90)
        this.ISASCAPE = true; 
      if (this.ISASCAPE)
        ascape(target.getLocation()); 
      attack(target);
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
  }
  
  private void Astarothfire() {
    int radius = 0;
    int damage = 0;
    switch (getNpcId()) {
      case 107037:
        radius = 3;
        damage = 200;
        break;
      case 99030:
        radius = 0;
        break;
      case 99083:
        radius = 0;
        break;
    } 
    Iterator<L1PcInstance> iterator = World.get().getVisiblePlayer((L1Object)this, radius).iterator();
    while (iterator.hasNext()) {
      L1PcInstance player = iterator.next();
      if (player != null) {
        if (getNpcId() == 99030) {
          if (this._target != null && this._target.getId() == player.getId()) {
            L1Teleport.teleport(player, 32990, 32990, (short)8001, 5, true);
            setSleepTime(5000);
            return;
          } 
        } else if (getNpcId() == 99083) {
          L1Location loc = player.getLocation();
          L1Location newloc = loc.randomLocation(100, true);
          L1Teleport.teleport(player, newloc, player.getHeading(), true);
          return;
        } 
        player.receiveDamage(this, damage, false, true);
        player.sendPacketsAll((ServerBasePacket)new S_DoActionGFX(player.getId(), 2));
        broadcastPacketAll((ServerBasePacket)new S_DoActionGFX(getId(), 11));
        deleteMe();
      } 
    } 
  }
  
  private void kirtasfire() {
    setSleepTime(1000);
    int radius = 0;
    int damage = 0;
    switch (getNpcId()) {
      case 86121:
        radius = 3;
        damage = 200;
        break;
      case 86122:
        radius = 2;
        damage = 100;
        break;
      case 97221:
        radius = 1;
        damage = 100;
        broadcastPacketAll((ServerBasePacket)new S_DoActionGFX(getId(), 19));
        break;
      case 99030:
      case 99084:
        radius = 0;
        break;
    } 
    Iterator<L1PcInstance> iterator = World.get().getVisiblePlayer((L1Object)this, radius).iterator();
    while (iterator.hasNext()) {
      L1PcInstance player = iterator.next();
      if (player != null) {
        if (getNpcId() == 99084) {
          if (_random.nextInt(100) < 70) {
            L1Location loc = player.getLocation();
            L1Location newloc = loc.randomLocation(100, true);
            L1Teleport.teleport(player, newloc, player.getHeading(), true);
          } else {
            L1Teleport.teleport(player, 32812, 33184, (short)4, player.getHeading(), true);
          } 
          return;
        } 
        if (getNpcId() == 99030) {
          L1Teleport.teleport(player, 32990, 32990, (short)8001, 5, true);
          return;
        } 
        player.receiveDamage(this, damage, true, true);
        player.sendPacketsAll((ServerBasePacket)new S_DoActionGFX(player.getId(), 2));
      } 
    } 
  }
  
  private void attack(L1Character target) {
    if (!isAiRunning())
      startAI(); 
    if (isAttackPosition(target.getX(), target.getY(), get_ranged())) {
      if (this._mobSkill.isSkillTrigger(target)) {
        if (_random.nextInt(2) >= 1) {
          setHeading(targetDirection(target.getX(), target.getY()));
          attackTarget(target);
        } else if (this._mobSkill.skillUse(target, true)) {
          setSleepTime(calcSleepTime(this._mobSkill.getSleepTime(), 2));
        } else {
          setHeading(targetDirection(target.getX(), target.getY()));
          attackTarget(target);
        } 
      } else {
        setHeading(targetDirection(target.getX(), target.getY()));
        attackTarget(target);
      } 
      if (this._npcMove != null)
        this._npcMove.clear(); 
    } else {
      if (this._target == null)
        return; 
      if (glanceCheck(this._target.getX(), this._target.getY()) && this._mobSkill.skillUse(target, false)) {
        setSleepTime(calcSleepTime(this._mobSkill.getSleepTime(), 2));
        return;
      } 
      if (getPassispeed() > 0) {
        int distance = getLocation().getTileDistance((Point)target.getLocation());
        if (this.firstFound && getNpcTemplate().is_teleport() && distance > 3 && distance < 20 && 
          nearTeleport(target.getX(), target.getY())) {
          this.firstFound = false;
          return;
        } 
        if (getNpcTemplate().is_teleport() && 20 > _random.nextInt(100) && 
          getCurrentMp() >= 10 && distance > 6 && distance < 20 && 
          nearTeleport(target.getX(), target.getY()))
          return; 
        if (this._npcMove != null) {
          int dir = this._npcMove.moveDirection(target.getX(), target.getY());
          if (dir == -1) {
            tagertClear();
          } else {
            this._npcMove.setDirectionMove(dir);
            setSleepTime(calcSleepTime(getPassispeed(), 0));
          } 
        } 
      } else {
        switch (getGfxId()) {
          case 816:
            attackTarget(target);
            return;
        } 
        tagertClear();
      } 
    } 
  }
  
  private void ascape(L1Location location) {
    int escapeDistance = 17;
    if (hasSkillEffect(40))
      escapeDistance = 1; 
    if (getLocation().getTileLineDistance((Point)location) > escapeDistance) {
      tagertClear();
    } else if (this._npcMove != null) {
      int dir = this._npcMove.targetReverseDirection(location.getX(), location.getY());
      dir = this._npcMove.checkObject(dir);
      dir = this._npcMove.openDoor(dir);
      this._npcMove.setDirectionMove(dir);
      setSleepTime(calcSleepTime(getPassispeed(), 0));
    } 
  }
  
  private boolean isTraget(L1Character cha) {
    boolean isTraget = false;
    if (cha instanceof L1PcInstance) {
      L1PcInstance tg = (L1PcInstance)cha;
      if (!tg.isSafetyZone())
        isTraget = true; 
    } else if (cha instanceof L1PetInstance) {
      L1PetInstance tg2 = (L1PetInstance)cha;
      if (!tg2.isSafetyZone())
        isTraget = true; 
    } else if (cha instanceof L1SummonInstance) {
      L1SummonInstance tg3 = (L1SummonInstance)cha;
      if (!tg3.isSafetyZone())
        isTraget = true; 
    } else if (cha instanceof L1MonsterInstance) {
      isTraget = true;
    } 
    return isTraget;
  }
  
  public void attackTarget(L1Character target) {
    if (this instanceof L1IllusoryInstance && !isTraget(target))
      return; 
    if (target instanceof L1PcInstance) {
      L1PcInstance player = (L1PcInstance)target;
      player.isTeleport();
    } else if (target instanceof L1PetInstance) {
      L1PetInstance pet = (L1PetInstance)target;
      L1Character cha = pet.getMaster();
      if (cha instanceof L1PcInstance) {
        L1PcInstance player2 = (L1PcInstance)cha;
        player2.isTeleport();
      } 
    } else if (target instanceof L1SummonInstance) {
      L1SummonInstance summon = (L1SummonInstance)target;
      L1Character cha = summon.getMaster();
      if (cha instanceof L1PcInstance) {
        L1PcInstance player2 = (L1PcInstance)cha;
        if (player2.isTeleport())
          return; 
      } 
    } 
    if (this instanceof L1PetInstance) {
      L1PetInstance pet = (L1PetInstance)this;
      L1Character cha = pet.getMaster();
      if (cha instanceof L1PcInstance) {
        L1PcInstance player2 = (L1PcInstance)cha;
        player2.isTeleport();
      } 
    } else if (this instanceof L1SummonInstance) {
      L1SummonInstance summon = (L1SummonInstance)this;
      L1Character cha = summon.getMaster();
      if (cha instanceof L1PcInstance) {
        L1PcInstance player2 = (L1PcInstance)cha;
        if (player2.isTeleport())
          return; 
      } 
    } 
    if (target instanceof L1NpcInstance) {
      L1NpcInstance npc = (L1NpcInstance)target;
      if (npc.getHiddenStatus() != 0) {
        allTargetClear();
        return;
      } 
    } 
    boolean isCounterBarrier = false;
    L1AttackNpc l1AttackNpc = new L1AttackNpc(this, target);
    if (l1AttackNpc.calcHit()) {
      if (target.hasSkillEffect(91)) {
        L1Magic magic = new L1Magic(target, this);
        boolean isProbability = magic.calcProbabilityMagic(91);
        boolean isShortDistance = l1AttackNpc.isShortDistance();
        if (isProbability && isShortDistance)
          isCounterBarrier = true; 
      } 
      if (!isCounterBarrier)
        l1AttackNpc.calcDamage(); 
    } 
    if (isCounterBarrier) {
      l1AttackNpc.commitCounterBarrier();
    } else {
      l1AttackNpc.action();
      l1AttackNpc.commit();
    } 
    setSleepTime(calcSleepTime(getAtkspeed(), 1));
  }
  
  public void searchTargetItem() {
    ArrayList<L1GroundInventory> gInventorys = new ArrayList<>();
    Iterator<L1Object> iterator = World.get().getVisibleObjects((L1Object)this).iterator();
    while (iterator.hasNext()) {
      L1Object obj = iterator.next();
      if (obj != null && obj instanceof L1GroundInventory)
        gInventorys.add((L1GroundInventory)obj); 
    } 
    if (gInventorys.size() == 0)
      return; 
    int pickupIndex = (int)(Math.random() * gInventorys.size());
    L1GroundInventory inventory = gInventorys.get(pickupIndex);
    Iterator<L1ItemInstance> iterator2 = inventory.getItems().iterator();
    while (iterator2.hasNext()) {
      L1ItemInstance item = iterator2.next();
      if (getInventory().checkAddItem(item, item.getCount()) == 0) {
        this._targetItem = item;
        this._targetItemList.add(this._targetItem);
      } 
    } 
  }
  
  public void searchItemFromAir() {
    ArrayList<L1GroundInventory> gInventorys = new ArrayList<>();
    Iterator<L1Object> iterator = World.get().getVisibleObjects((L1Object)this).iterator();
    while (iterator.hasNext()) {
      L1Object obj = iterator.next();
      if (obj != null && obj instanceof L1GroundInventory)
        gInventorys.add((L1GroundInventory)obj); 
    } 
    if (gInventorys.size() == 0)
      return; 
    int pickupIndex = (int)(Math.random() * gInventorys.size());
    L1GroundInventory inventory = gInventorys.get(pickupIndex);
    Iterator<L1ItemInstance> iterator2 = inventory.getItems().iterator();
    while (iterator2.hasNext()) {
      L1ItemInstance item = iterator2.next();
      if ((item.getItem().getType() == 6 || item.getItem().getType() == 7) && 
        getInventory().checkAddItem(item, item.getCount()) == 0 && getHiddenStatus() == 2) {
        setHiddenStatus(0);
        broadcastPacketAll((ServerBasePacket)new S_DoActionGFX(getId(), 45));
        setStatus(0);
        broadcastPacketAll((ServerBasePacket)new S_NPCPack(this));
        onNpcAI();
        startChat(2);
        this._targetItem = item;
        this._targetItemList.add(this._targetItem);
      } 
    } 
  }
  
  public void checkTargetItem() {
    if (this._targetItem == null || this._targetItem.getMapId() != getMapId() || 
      getLocation().getTileDistance((Point)this._targetItem.getLocation()) > 15)
      if (!this._targetItemList.isEmpty()) {
        this._targetItem = this._targetItemList.get(0);
        this._targetItemList.remove(0);
        checkTargetItem();
      } else {
        this._targetItem = null;
      }  
  }
  
  public void onTargetItem() {
    if (getLocation().getTileLineDistance((Point)this._targetItem.getLocation()) == 0) {
      pickupTargetItem(this._targetItem);
    } else if (this._npcMove != null) {
      int dir = this._npcMove.moveDirection(this._targetItem.getX(), this._targetItem.getY());
      if (dir == -1) {
        this._targetItemList.remove(this._targetItem);
        this._targetItem = null;
      } else {
        this._npcMove.setDirectionMove(dir);
        setSleepTime(calcSleepTime(getPassispeed(), 0));
      } 
    } 
  }
  
  public void pickupTargetItem(L1ItemInstance targetItem) {
    try {
      int x = targetItem.getX();
      int y = targetItem.getY();
      short m = targetItem.getMapId();
      L1GroundInventory l1GroundInventory = World.get().getInventory(x, y, m);
      L1ItemInstance item = l1GroundInventory.tradeItem(targetItem, targetItem.getCount(), getInventory());
      onGetItem(item);
      this._targetItemList.remove(this._targetItem);
      this._targetItem = null;
      setSleepTime(1000);
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
  }
  
//  public boolean noTarget() {
//    switch (getNpcId()) {
//      case 86121:
//      case 86122:
//      case 97221:
//      case 99084:
//        kirtasfire();
//        break;
//    } 
//    if (World.get().getVisiblePlayer((L1Object)this).isEmpty())
//      return true; 
//    if (this._master != null && this._master.getMapId() == getMapId() && 
//      getLocation().getTileLineDistance((Point)this._master.getLocation()) > 2) {
//      int dir = this._npcMove.moveDirection(this._master.getX(), this._master.getY());
//      if (dir == -1)
//        return true; 
//      this._npcMove.setDirectionMove(dir);
//      setSleepTime(calcSleepTime(getPassispeed(), 0));
//      return false;
//    } 
//    if (World.get().getVisiblePlayer((L1Object)this, 20).size() <= 0) {
//      teleport(getHomeX(), getHomeY(), getHeading());
//      return true;
//    } 
//    if (this._master == null && getPassispeed() > 0 && !isRest()) {
//      L1MobGroupInfo mobGroupInfo = getMobGroupInfo();
//      if (mobGroupInfo == null || (mobGroupInfo != null && mobGroupInfo.isLeader(this))) {
//        if (this._randomMoveDistance == 0) {
//          this._randomMoveDistance = _random.nextInt(5) + 1;
//          this._randomMoveDirection = _random.nextInt(20);
//          if (getHomeX() != 0 && getHomeY() != 0 && this._randomMoveDirection < 8 && 
//            _random.nextInt(3) == 0)
//            this._randomMoveDirection = this._npcMove.moveDirection(getHomeX(), getHomeY()); 
//          return false;
//        } 
//        this._randomMoveDistance--;
//        int dir2 = checkObject(getX(), getY(), getMapId(), this._randomMoveDirection);
//        if (dir2 != -1) {
//          this._npcMove.setDirectionMove(dir2);
//          setSleepTime(calcSleepTime(getPassispeed(), 0));
//        } 
//        return false;
//      } 
//      L1NpcInstance leader = mobGroupInfo.getLeader();
//      if (getPassispeed() > 0 && getLocation().getTileLineDistance((Point)leader.getLocation()) > 2 && 
//        this._npcMove != null) {
//        int dir3 = this._npcMove.moveDirection(leader.getX(), leader.getY());
//        if (dir3 == -1)
//          return true; 
//        this._npcMove.setDirectionMove(dir3);
//        setSleepTime(calcSleepTime(getPassispeed(), 0));
//      } 
//    } 
//    return false;
//  }
  
	public boolean noTarget() {

		switch (this.getNpcId()) {
		case 86121:
		case 86122:
		case 97221:// 奇怪的乌云
		case 99084:// 沙漠地区 沙尘暴
			kirtasfire();
			break;
		}

		// 具有主人 并在同地图 与主人超过两格距离
		if ((_master != null) && (_master.getMapId() == getMapId())
				&& (getLocation().getTileLineDistance(_master.getLocation()) > 2)) {
			if (getPassispeed() > 0) {// 具备移动速度
				if (_npcMove != null) {
					// 跟随主人移动
					final int dir = _npcMove.moveDirection(_master.getX(), _master.getY());
					if (dir != -1) {
						_npcMove.setDirectionMove(dir);
						setSleepTime(calcSleepTime(getPassispeed(), MOVE_SPEED));
					} else {
						return true;
					}

				} else {
					return true;
				}
			}

		} else {// 没有主人
			// 周边无PC物件 AI处理终止
			if (World.get().getVisiblePlayer(this, DISTANCE).size() <= 0) {
				if (this.getMapId() != 93) {// 不是怪物对战地图
					teleport(getHomeX(), getHomeY(), getHeading());// 传回出生点
					return true;
				}
			}
			// 没有队长 具有移动速度 并未动作暂停
			if ((_master == null) && (getPassispeed() > 0) && !isRest()) {
				// NPC不具有队伍状态 或本身是队长
				final L1MobGroupInfo mobGroupInfo = getMobGroupInfo();
				if ((mobGroupInfo == null) || ((mobGroupInfo != null) && mobGroupInfo.isLeader(this))) {

					// 如果移动距离已经为0 重新定义随机移动
					if (_randomMoveDistance == 0) {
						// 产生移动距离
						_randomMoveDistance = _random.nextInt(6) + 1;

						// 产生移动方向(随机数值超出7物件会暂停移动)
						_randomMoveDirection = _random.nextInt(40);

						// 返回出生点的判断
						if ((getHomeX() != 0) && (getHomeY() != 0)// 具有出生点设置
								&& (_randomMoveDirection < 8)) {// 具有移动方向
							if (getLocation().getLineDistance(new Point(getHomeX(), getHomeY())) > 8) {// 距离超过出生点8格
								if (_npcMove != null) {
									_randomMoveDirection = _npcMove.moveDirection(getHomeX(), getHomeY());
								}
							}
						}

					} else {
						_randomMoveDistance--;// 移动距离-1
					}

					if (_npcMove != null) {
						if (_randomMoveDirection < 8) {// 具有移动方向
							int dir = _npcMove.checkObject(_randomMoveDirection);
							dir = _npcMove.openDoor(dir);

							if (dir != -1) {
								_npcMove.setDirectionMove(dir);
								setSleepTime(calcSleepTime(getPassispeed(), MOVE_SPEED));
							}
						}
					}

				} else { // NPC具有队伍状态
					// 领队追寻
					final L1NpcInstance leader = mobGroupInfo.getLeader();
					if (getPassispeed() > 0) {
						if (getLocation().getTileLineDistance(leader.getLocation()) > 2) {
							if (_npcMove != null) {
								final int dir = _npcMove.moveDirection(leader.getX(), leader.getY());
								if (dir == -1) {
									return true;

								} else {
									_npcMove.setDirectionMove(dir);
									setSleepTime(calcSleepTime(getPassispeed(), MOVE_SPEED));
								}
							}
						}
					}
				}
			}
		}
		return false;
	}
  
  public void onFinalAction(L1PcInstance pc, String s) {}
  
  private void tagertClear() {
    if (this._target == null)
      return; 
    this._hateList.remove(this._target);
    this._target = null;
  }
  
  public void targetRemove(L1Character target) {
    this._hateList.remove(target);
    if (this._target != null && this._target.equals(target))
      this._target = null; 
  }
  
  public void allTargetClear() {
    if (this._npcMove != null)
      this._npcMove.clear(); 
    this._hateList.clear();
    this._dropHateList.clear();
    this._target = null;
    this._targetItemList.clear();
    this._targetItem = null;
  }
  
  public L1Character getMaster() {
    return this._master;
  }
  
  public void setMaster(L1Character cha) {
    this._master = cha;
  }
  
  public void onNpcAI() {}
  
  public void refineItem() {
    int[] materials = null;
    int[] counts = null;
    int[] createitem = null;
    int[] createcount = null;
    if (this._npcTemplate.get_npcId() == 105078 && this._inventory.checkItem(40054)) {
      broadcastPacketAll((ServerBasePacket)new S_DoActionGFX(getId(), 2));
      setStatus(0);
      setHiddenStatus(0);
      broadcastPacketAll((ServerBasePacket)new S_NPCPack(this));
    } 
    if (this._npcTemplate.get_npcId() == 45032) {
      if (getExp() != 0L && !this._inventory.checkItem(20)) {
        materials = new int[] { 40508, 40521, 40045 };
        counts = new int[] { 150, 3, 3 };
        createitem = new int[] { 20 };
        createcount = new int[] { 1 };
        if (this._inventory.checkItem(materials, counts)) {
          int i = 0;
          while (i < materials.length) {
            this._inventory.consumeItem(materials[i], counts[i]);
            i++;
          } 
          int j = 0;
          while (j < createitem.length) {
            this._inventory.storeItem(createitem[j], createcount[j]);
            j++;
          } 
        } 
      } 
      if (getExp() != 0L && !this._inventory.checkItem(19)) {
        materials = new int[] { 40494, 40521 };
        counts = new int[] { 150, 3 };
        createitem = new int[] { 19 };
        createcount = new int[] { 1 };
        if (this._inventory.checkItem(materials, counts)) {
          int i = 0;
          while (i < materials.length) {
            this._inventory.consumeItem(materials[i], counts[i]);
            i++;
          } 
          int j = 0;
          while (j < createitem.length) {
            this._inventory.storeItem(createitem[j], createcount[j]);
            j++;
          } 
        } 
      } 
      if (getExp() != 0L && !this._inventory.checkItem(3)) {
        materials = new int[] { 40494, 40521 };
        counts = new int[] { 50, 1 };
        createitem = new int[] { 3 };
        createcount = new int[] { 1 };
        if (this._inventory.checkItem(materials, counts)) {
          int i = 0;
          while (i < materials.length) {
            this._inventory.consumeItem(materials[i], counts[i]);
            i++;
          } 
          int j = 0;
          while (j < createitem.length) {
            this._inventory.storeItem(createitem[j], createcount[j]);
            j++;
          } 
        } 
      } 
      if (getExp() != 0L && !this._inventory.checkItem(100)) {
        materials = new int[] { 88, 40508, 40045 };
        counts = new int[] { 4, 80, 3 };
        createitem = new int[] { 100 };
        createcount = new int[] { 1 };
        if (this._inventory.checkItem(materials, counts)) {
          int i = 0;
          while (i < materials.length) {
            this._inventory.consumeItem(materials[i], counts[i]);
            i++;
          } 
          int j = 0;
          while (j < createitem.length) {
            this._inventory.storeItem(createitem[j], createcount[j]);
            j++;
          } 
        } 
      } 
      if (getExp() != 0L && !this._inventory.checkItem(89)) {
        materials = new int[] { 88, 40494 };
        counts = new int[] { 2, 80 };
        createitem = new int[] { 89 };
        createcount = new int[] { 1 };
        if (this._inventory.checkItem(materials, counts)) {
          int i = 0;
          while (i < materials.length) {
            this._inventory.consumeItem(materials[i], counts[i]);
            i++;
          } 
          int j = 0;
          while (j < createitem.length) {
            L1ItemInstance item = this._inventory.storeItem(createitem[j], createcount[j]);
            if (getNpcTemplate().get_digestitem() > 0)
              setDigestItem(item); 
            j++;
          } 
        } 
      } 
    } else if ((this._npcTemplate.get_npcId() == 45166 || this._npcTemplate.get_npcId() == 45167) && 
      getExp() != 0L && !this._inventory.checkItem(40726)) {
      materials = new int[] { 40725 };
      counts = new int[] { 1 };
      createitem = new int[] { 40726 };
      createcount = new int[] { 1 };
      if (this._inventory.checkItem(materials, counts)) {
        int i = 0;
        while (i < materials.length) {
          this._inventory.consumeItem(materials[i], counts[i]);
          i++;
        } 
        int j = 0;
        while (j < createitem.length) {
          this._inventory.storeItem(createitem[j], createcount[j]);
          j++;
        } 
      } 
    } 
  }
  
  public L1HateList getHateList() {
    return this._hateList;
  }
  
  public final boolean isHpR() {
    return (!destroyed() && !isDead() && getMaxHp() > 0 && getCurrentHp() > 0 && 
      getCurrentHp() < getMaxHp());
  }
  
  public final void startHpRegeneration() {
    if (destroyed() && isDead())
      return; 
    if (getCurrentHp() <= 0)
      return; 
    if (!this._hprRunning)
      this._hprRunning = true; 
  }
  
  public final boolean isHpRegenerationX() {
    return this._hprRunning;
  }
  
  public final void stopHpRegeneration() {
    if (this._hprRunning)
      this._hprRunning = false; 
  }
  
  public final boolean isMpR() {
    return (!destroyed() && !isDead() && getMaxHp() > 0 && getMaxMp() > 0 && 
      getCurrentHp() > 0 && getCurrentMp() < getMaxMp());
  }
  
  public final void startMpRegeneration() {
    if (destroyed() && isDead())
      return; 
    if (getCurrentHp() <= 0)
      return; 
    if (!this._mprRunning)
      this._mprRunning = true; 
  }
  
  public final boolean isMpRegenerationX() {
    return this._mprRunning;
  }
  
  public final void stopMpRegeneration() {
    if (this._mprRunning)
      this._mprRunning = false; 
  }
  
  public void setting_template(L1Npc template) {
    this._npcTemplate = template;
    int randomlevel = 0;
    double rate = 0.0D;
    double diff = 0.0D;
    setName(template.get_name());
    String name = String.valueOf(String.valueOf(newName(template.get_npcId()))) + template.get_nameid();
    setNameId(name);
    if (template.get_randomlevel() == 0) {
      setLevel(template.get_level());
    } else {
      randomlevel = _random.nextInt(template.get_randomlevel() - template.get_level() + 1);
      diff = (template.get_randomlevel() - template.get_level());
      rate = randomlevel / diff;
      randomlevel += template.get_level();
      setLevel(randomlevel);
    } 
    if (template.get_randomhp() == 0) {
      setMaxHp(template.get_hp());
      setCurrentHpDirect(template.get_hp());
    } else {
      double randomhp = rate * (template.get_randomhp() - template.get_hp());
      int hp = (int)(template.get_hp() + randomhp);
      setMaxHp(hp);
      setCurrentHpDirect(hp);
    } 
    if (template.get_randommp() == 0) {
      setMaxMp(template.get_mp());
      setCurrentMpDirect(template.get_mp());
    } else {
      double randommp = rate * (template.get_randommp() - template.get_mp());
      int mp = (int)(template.get_mp() + randommp);
      setMaxMp(mp);
      setCurrentMpDirect(mp);
    } 
    if (template.get_randomac() == 0) {
      setAc(template.get_ac());
    } else {
      double randomac = rate * (template.get_randomac() - template.get_ac());
      int ac = (int)(template.get_ac() + randomac);
      setAc(ac);
    } 
    if (template.get_randomlevel() == 0) {
      setStr(template.get_str());
      setCon(template.get_con());
      setDex(template.get_dex());
      setInt(template.get_int());
      setWis(template.get_wis());
      setMr(template.get_mr());
    } else {
      setStr((byte)(int)Math.min(template.get_str() + diff, 127.0D));
      setCon((byte)(int)Math.min(template.get_con() + diff, 127.0D));
      setDex((byte)(int)Math.min(template.get_dex() + diff, 127.0D));
      setInt((byte)(int)Math.min(template.get_int() + diff, 127.0D));
      setWis((byte)(int)Math.min(template.get_wis() + diff, 127.0D));
      setMr((byte)(int)Math.min(template.get_mr() + diff, 127.0D));
      addHitup((int)diff * 2);
      addDmgup((int)diff * 2);
    } 
    setPassispeed(template.get_passispeed());
    setAtkspeed(template.get_atkspeed());
    setAgro(template.is_agro());
    setAgrocoi(template.is_agrocoi());
    setAgrososc(template.is_agrososc());
    if (getNpcTemplate().get_weakAttr() != 0)
      switch (getNpcTemplate().get_weakAttr()) {
        case 1:
          addEarth(-50);
          break;
        case 2:
          addFire(-50);
          break;
        case 4:
          addWater(-50);
          break;
        case 8:
          addWind(-50);
          break;
        case -1:
          addEarth(50);
          break;
        case -2:
          addFire(50);
          break;
        case -4:
          addWater(50);
          break;
        case -8:
          addWind(50);
          break;
      }  
    int gfxid = newGfx(template.get_gfxid());
    setTempCharGfx(gfxid);
    setGfxId(gfxid);
    setGfxidInStatus(gfxid);
    if (template.get_randomexp() == 0) {
      setExp(template.get_exp());
    } else {
      int level = getLevel();
      int exp = level * level;
      exp++;
      setExp(exp);
    } 
    if (template.get_randomlawful() == 0) {
      setLawful(template.get_lawful());
      setTempLawful(template.get_lawful());
    } else {
      double randomlawful = rate * (template.get_randomlawful() - template.get_lawful());
      int lawful = (int)(template.get_lawful() + randomlawful);
      setLawful(lawful);
      setTempLawful(lawful);
    } 
    setPickupItem(template.is_picupitem());
    if (template.is_bravespeed()) {
      setBraveSpeed(1);
    } else {
      setBraveSpeed(0);
    } 
    setKarma(template.getKarma());
    setLightSize(template.getLightSize());
    if (template.talk())
      this.TALK = template.getNpcExecutor(); 
    if (template.action())
      this.ACTION = template.getNpcExecutor(); 
    if (template.attack())
      this.ATTACK = template.getNpcExecutor(); 
    if (template.death())
      this.DEATH = template.getNpcExecutor(); 
    if (template.work()) {
      this.WORK = template.getNpcExecutor();
      if (this.WORK.workTime() != 0) {
        NpcWorkTimer.put(this, Integer.valueOf(this.WORK.workTime()));
      } else {
        this.WORK.work(this);
      } 
    } 
    if (template.spawn())
      (this.SPAWN = template.getNpcExecutor()).spawn(this); 
    this._mobSkill = new L1MobSkillUse(this);
  }
  
  public void setGfxidInStatus(int gfxid) {
    switch (gfxid) {
      case 51:
      case 110:
      case 147:
        setStatus(24);
        break;
      case 57:
      case 816:
      case 3137:
      case 3140:
      case 3145:
      case 3148:
      case 3151:
      case 7621:
      case 10649:
      case 11714:
        setStatus(20);
        break;
      case 111:
        setStatus(4);
        break;
    } 
  }
  
  private String newName(int npcid) {
    String color = "";
    return color;
  }
  
  private int newGfx(int get_gfxid) {
    int[] r = null;
    switch (get_gfxid) {
      case 998:
      case 999:
      case 1002:
      case 1003:
        r = new int[] { 998, 999, 1002, 1003 };
        break;
      case 1597:
      case 1600:
        r = new int[] { 1597, 1600 };
        break;
      case 5942:
        r = new int[] { 
            5942, 5135, 5137, 5139, 5141, 5143, 5145, 5156, 5158, 5160, 
            5162 };
        break;
      case 1318:
      case 1321:
        r = new int[] { 1318, 1321 };
        break;
    } 
    if (r != null) {
      int newgfx = _random.nextInt(r.length);
      get_gfxid = r[newgfx];
    } 
    return get_gfxid;
  }
  
  public int getPassispeed() {
    return this._passispeed;
  }
  
  public void setPassispeed(int i) {
    this._passispeed = i;
  }
  
  public int getAtkspeed() {
    return this._atkspeed;
  }
  
  public void setAtkspeed(int i) {
    this._atkspeed = i;
  }
  
  public boolean isPickupItem() {
    return this._pickupItem;
  }
  
  public void setPickupItem(boolean flag) {
    this._pickupItem = flag;
  }
  
  public L1Inventory getInventory() {
    return this._inventory;
  }
  
  public void setInventory(L1Inventory inventory) {
    this._inventory = inventory;
  }
  
  public L1Npc getNpcTemplate() {
    return this._npcTemplate;
  }
  
  public int getNpcId() {
    return this._npcTemplate.get_npcId();
  }
  
  public int getPetcost() {
    return this._petcost;
  }
  
  public void setPetcost(int i) {
    this._petcost = i;
  }
  
  public L1Spawn getSpawn() {
    return this._spawn;
  }
  
  public void setSpawn(L1Spawn spawn) {
    this._spawn = spawn;
  }
  
  public int getSpawnNumber() {
    return this._spawnNumber;
  }
  
  public void setSpawnNumber(int number) {
    this._spawnNumber = number;
  }
  
  public void onDecay(boolean isReuseId) {
    int id = 0;
    if (isReuseId) {
      id = getId();
    } else {
      id = 0;
    } 
    this._spawn.executeSpawnTask(this._spawnNumber, id);
  }
  
  public void onPerceive(L1PcInstance perceivedFrom) {
    try {
      perceivedFrom.addKnownObject((L1Object)this);
      perceivedFrom.sendPackets((ServerBasePacket)new S_NPCPack(this));
      onNpcAI();
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
  }
  
  public void deleteMe() {
    if (this._destroyed)
      return; 
    int tgid = 0;
    if (this instanceof L1IllusoryInstance && getMaster() != null && 
      getMaster() instanceof L1PcInstance) {
      L1PcInstance masterPc = (L1PcInstance)getMaster();
      if (masterPc != null)
        masterPc.get_otherList().removeIllusoryList(Integer.valueOf(getId())); 
    } 
    L1NpcInstance tgMob = null;
    if (tgid != 0) {
      ArrayList<L1Object> list = World.get().getVisibleObjects((L1Object)this);
      Iterator<L1Object> iterator = list.iterator();
      while (iterator.hasNext()) {
        L1Object objects = iterator.next();
        if (objects instanceof L1NpcInstance) {
          L1NpcInstance tgMobR = (L1NpcInstance)objects;
          if (tgMobR.getNpcId() != tgid)
            continue; 
          if (!tgMobR.isDead()) {
            resurrect(getMaxHp());
            return;
          } 
          if (!tgMobR._destroyed) {
            tgMob = tgMobR;
            break;
          } 
        } 
      } 
    } 
    this._destroyed = true;
    if (!(this instanceof L1PetInstance) && getInventory() != null)
      getInventory().clearItems(); 
    allTargetClear();
    this._master = null;
    int showid = get_showId();
    if (WorldQuest.get().isQuest(showid))
      WorldQuest.get().remove(showid, this); 
    if (!getDolls().isEmpty()) {
      Object[] array;
      int length = (array = getDolls().values().toArray()).length;
      int i = 0;
      while (i < length) {
        Object obj = array[i];
        L1DollInstance doll = (L1DollInstance)obj;
        if (doll != null)
          doll.deleteDoll(); 
        i++;
      } 
    } 
    if (!getPetList().isEmpty()) {
      Object[] array2;
      int length2 = (array2 = getPetList().values().toArray()).length;
      int j = 0;
      while (j < length2) {
        Object obj2 = array2[j];
        L1NpcInstance summon = (L1NpcInstance)obj2;
        if (summon != null && summon instanceof L1SummonInstance) {
          L1SummonInstance su = (L1SummonInstance)summon;
          su.deleteMe();
        } 
        j++;
      } 
    } 
    this._hateList.clear();
    this._dropHateList.clear();
    this._targetItemList.clear();
    this._del_map.clear();
    World.get().removeVisibleObject((L1Object)this);
    World.get().removeObject((L1Object)this);
    List<L1PcInstance> players = World.get().getRecognizePlayer((L1Object)this);
    if (players.size() > 0) {
      Iterator<L1PcInstance> iterator2 = players.iterator();
      while (iterator2.hasNext()) {
        L1PcInstance tgpc = iterator2.next();
        if (tgpc != null) {
          if (getTempCharGfx() == 10947)
            tgpc.sendPackets((ServerBasePacket)new S_DoActionGFX(getId(), 8)); 
          tgpc.removeKnownObject((L1Object)this);
          tgpc.sendPackets((ServerBasePacket)new S_RemoveObject((L1Object)this));
        } 
      } 
    } 
    removeAllKnownObjects();
    if (tgMob != null)
      tgMob.deleteMe(); 
    try {
      if (getNpcTemplate().is_boss() && this._spawn.get_nextSpawnTime() != null) {
        Date spawnTime;
        String nextTime;
        long newTime = 0L;
        long minTime = this._spawn.get_spawnInterval();
        long maxTime = this._spawn.get_spawnIntervalMax();
        if (maxTime != 0L || maxTime > minTime)
          minTime += _random.nextInt((int)(maxTime - minTime)); 
        newTime = minTime * 60L * 1000L;
        Calendar cals = Calendar.getInstance();
        cals.setTimeInMillis(System.currentTimeMillis() + newTime);
        this._spawn.get_nextSpawnTime().setTimeInMillis(cals.getTimeInMillis());
        SpawnBossReading.get().upDateNextSpawnTime(this._spawn.getId(), cals);
        switch (this._spawn.getHeading()) {
          case 0:
            spawnTime = this._spawn.get_nextSpawnTime().getTime();
            nextTime = (new SimpleDateFormat("yyyy/MM/dd HH:mm")).format(spawnTime);
            World.get().broadcastPacketToAll(
                (ServerBasePacket)new S_ServerMessage(String.valueOf(String.valueOf(getNameId())) + "已经死亡，下次出现时间" + nextTime));
            break;
          case 1:
            World.get().broadcastPacketToAll((ServerBasePacket)new S_ServerMessage(String.valueOf(String.valueOf(getNameId())) + "已经死亡!"));
            break;
        } 
      } 
    } catch (Exception exception) {}
    L1MobGroupInfo mobGroupInfo = getMobGroupInfo();
    if (mobGroupInfo != null && mobGroupInfo.removeMember(this) == 0)
      setMobGroupInfo((L1MobGroupInfo)null); 
    if (isReSpawn())
      this._spawn.executeSpawnTask(this._spawnNumber, 0); 
  }
  
  public void outParty(L1NpcInstance mob) {
    Collection<L1NpcInstance> list = WorldNpc.get().all();
    Iterator<L1NpcInstance> iterator = list.iterator();
    while (iterator.hasNext()) {
      L1NpcInstance tgNpc = iterator.next();
      if (tgNpc.isDead())
        continue; 
      if (tgNpc.getMaster() == null)
        continue; 
      if (!tgNpc.getMaster().equals(mob))
        continue; 
      tgNpc.broadcastPacketAll((ServerBasePacket)new S_SkillSound(tgNpc.getId(), 2236));
      tgNpc.deleteMe();
    } 
  }
  
  public void ReceiveManaDamage(L1Character attacker, int damageMp) {}
  
  public void receiveDamage(L1Character attacker, int damage) {}
  
  public HashMap<L1ItemInstance, DelItemTime> getDigestItem() {
    return this._del_map;
  }
  
  public void setDigestItem(L1ItemInstance item) {
    DelItemTime delItemTime = new DelItemTime();
    delItemTime._del_item_time = getNpcTemplate().get_digestitem();
    this._del_map.put(item, delItemTime);
  }
  
  public void getDigestItemClear() {
    this._del_map.clear();
  }
  
  public boolean getDigestItemEmpty() {
    return this._del_map.isEmpty();
  }
  
  public void onGetItem(L1ItemInstance item) {
    refineItem();
    getInventory().shuffle();
    if (getNpcTemplate().get_digestitem() > 0)
      setDigestItem(item); 
  }
  
  public void approachPlayer(L1PcInstance pc) {
    if (pc.hasSkillEffect(60) || pc.hasSkillEffect(97) || pc.isGmInvis())
      return; 
    switch (getHiddenStatus()) {
      case 1:
        if (getCurrentHp() == getMaxHp() && 
          pc.getLocation().getTileLineDistance((Point)getLocation()) <= 2)
          appearOnGround(pc); 
        break;
      case 2:
        if (getCurrentHp() != getMaxHp()) {
          searchItemFromAir();
          break;
        } 
        if (pc.getLocation().getTileLineDistance((Point)getLocation()) <= 1)
          appearOnGround(pc); 
        break;
      case 3:
        if (getCurrentHp() < getMaxHp())
          appearOnGround(pc); 
        break;
      case 4:
        if (getCurrentHp() == getMaxHp() || getbarrierTime() > 15)
          appearOnGround(pc); 
        break;
    } 
  }
  
  public void startKIRTAS_Timer() {
    this._kirtastimer = new KIRTAS_Timer(this);
    Timer timer = new Timer(true);
    timer.scheduleAtFixedRate((TimerTask)this._kirtastimer, 1000L, 1000L);
  }
  
  public void stopKIRTAS_Timer() {
    this._kirtastimer.cancel();
    this._kirtastimer = null;
  }
  
  public final int getbarrierTime() {
    return this._barrierTime;
  }
  
  public final void setbarrierTime(int i) {
    this._barrierTime = i;
  }
  
  public void appearOnGround(L1PcInstance pc) {
    switch (getHiddenStatus()) {
      case 1:
      case 3:
        setHiddenStatus(0);
        if (getTempCharGfx() == 1245) {
          broadcastPacketAll((ServerBasePacket)new S_DoActionGFX(getId(), 11));
        } else {
          broadcastPacketAll((ServerBasePacket)new S_DoActionGFX(getId(), 4));
        } 
        setStatus(0);
        broadcastPacketAll((ServerBasePacket)new S_NPCPack(this));
        if (!pc.hasSkillEffect(60) && !pc.hasSkillEffect(97) && !pc.isGm()) {
          this._hateList.add(pc, 0);
          this._target = pc;
        } 
        onNpcAI();
        break;
      case 4:
        if (hasSkillEffect(11060) && !hasSkillEffect(11057)) {
          killSkillEffectTimer(11060);
          broadcastPacketAll((ServerBasePacket)new S_DoActionGFX(getId(), 21));
        } else if (hasSkillEffect(11059) && !hasSkillEffect(11057)) {
          killSkillEffectTimer(11059);
          broadcastPacketAll((ServerBasePacket)new S_DoActionGFX(getId(), 41));
        } else if (hasSkillEffect(11058)) {
          killSkillEffectTimer(11058);
          killSkillEffectTimer(78);
          broadcastPacketAll((ServerBasePacket)new S_DoActionGFX(getId(), 5));
        } else if (hasSkillEffect(11057)) {
          killSkillEffectTimer(11057);
          killSkillEffectTimer(11060);
          killSkillEffectTimer(11059);
          broadcastPacketAll((ServerBasePacket)new S_DoActionGFX(getId(), 25));
        } 
        setbarrierTime(0);
        stopKIRTAS_Timer();
        setHiddenStatus(0);
        setStatus(0);
        broadcastPacketAll((ServerBasePacket)new S_NPCPack(this));
        if (!pc.hasSkillEffect(60) && !pc.hasSkillEffect(97) && !pc.isGm()) {
          this._hateList.add(pc, 0);
          this._target = pc;
        } 
        onNpcAI();
        break;
      case 2:
        setHiddenStatus(0);
        broadcastPacketAll((ServerBasePacket)new S_DoActionGFX(getId(), 45));
        setStatus(0);
        broadcastPacketAll((ServerBasePacket)new S_NPCPack(this));
        if (!pc.hasSkillEffect(60) && !pc.hasSkillEffect(97) && !pc.isGm()) {
          this._hateList.add(pc, 0);
          this._target = pc;
        } 
        onNpcAI();
        startChat(2);
        break;
    } 
  }
  
  public L1Character is_now_target() {
    return this._target;
  }
  
  public void setNowTarget(L1Character target) {
    if (!isAiRunning())
      startAI(); 
    this._target = target;
  }
  
  public L1ItemInstance is_now_targetItem() {
    return this._targetItem;
  }
  
  public void set_now_targetItem(L1ItemInstance item) {
    this._targetItem = item;
  }
  
  public NpcMoveExecutor getMove() {
    return this._npcMove;
  }
  
  private void useHealPotion(int healHp, int effectId) {
    broadcastPacketAll((ServerBasePacket)new S_SkillSound(getId(), effectId));
    if (hasSkillEffect(173))
      healHp >>= 1; 
    if (hasSkillEffect(4012))
      healHp >>= 1; 
    if (hasSkillEffect(4011))
      healHp *= -1; 
    if (this instanceof L1PetInstance) {
      ((L1PetInstance)this).setCurrentHp(getCurrentHp() + healHp);
    } else if (this instanceof L1SummonInstance) {
      ((L1SummonInstance)this).setCurrentHp(getCurrentHp() + healHp);
    } else {
      setCurrentHpDirect(getCurrentHp() + healHp);
    } 
  }
  
  private void useHastePotion(int time) {
    broadcastPacketAll((ServerBasePacket)new S_SkillHaste(getId(), 1, time));
    broadcastPacketAll((ServerBasePacket)new S_SkillSound(getId(), 191));
    setMoveSpeed(1);
    setSkillEffect(1001, time * 1000);
  }
  
  public void useItem(int type, int chance) {
    if (is_decay_potion())
      return; 
    if (_random.nextInt(100) > chance)
      return; 
    if (getInventory() == null)
      return; 
    switch (type) {
      case 0:
        if (getInventory().consumeItem(40012, 1L)) {
          useHealPotion(75, 197);
          break;
        } 
        if (getInventory().consumeItem(40011, 1L)) {
          useHealPotion(45, 194);
          break;
        } 
        if (getInventory().consumeItem(40010, 1L))
          useHealPotion(15, 189); 
        break;
      case 1:
        if (hasSkillEffect(1001))
          return; 
        if (getInventory().consumeItem(140018, 1L)) {
          useHastePotion(2100);
          break;
        } 
        if (getInventory().consumeItem(40018, 1L)) {
          useHastePotion(1800);
          break;
        } 
        if (getInventory().consumeItem(140013, 1L)) {
          useHastePotion(350);
          break;
        } 
        if (getInventory().consumeItem(40013, 1L))
          useHastePotion(300); 
        break;
    } 
  }
  
  public void setDirectionMoveSrc(int dir) {
    if (dir >= 0 && dir <= 7) {
      int locx = getX() + L1Character.HEADING_TABLE_X[dir];
      int locy = getY() + L1Character.HEADING_TABLE_Y[dir];
      setHeading(dir);
      setX(locx);
      setY(locy);
    } 
  }
  
  public boolean nearTeleport(int nx, int ny) {
    int rdir = _random.nextInt(8);
    int i = 0;
    while (i < 8) {
      int dir = rdir + i;
      if (dir > 7)
        dir -= 8; 
      nx += L1Character.HEADING_TABLE_X[dir];
      ny += L1Character.HEADING_TABLE_Y[dir];
      if (getMap().isPassable(nx, ny, this)) {
        dir += 4;
        if (dir > 7)
          dir -= 8; 
        teleport(nx, ny, dir);
        setCurrentMp(getCurrentMp() - 10);
        return true;
      } 
      i++;
    } 
    return false;
  }
  
  public void teleport(int nx, int ny, int heading) {
    try {
      Iterator<L1PcInstance> iterator = World.get().getRecognizePlayer((L1Object)this).iterator();
      while (iterator.hasNext()) {
        L1PcInstance pc = iterator.next();
        pc.sendPackets((ServerBasePacket)new S_SkillSound(getId(), 169));
        pc.sendPackets((ServerBasePacket)new S_RemoveObject((L1Object)this));
        pc.removeKnownObject((L1Object)this);
      } 
      setX(nx);
      setY(ny);
      setHeading(heading);
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
  }
  
  public String getNameId() {
    return this._nameId;
  }
  
  public void setNameId(String s) {
    this._nameId = s;
  }
  
  public boolean isAgro() {
    return this._Agro;
  }
  
  public void setAgro(boolean flag) {
    this._Agro = flag;
  }
  
  public boolean isAgrocoi() {
    return this._Agrocoi;
  }
  
  public void setAgrocoi(boolean flag) {
    this._Agrocoi = flag;
  }
  
  public boolean isAgrososc() {
    return this._Agrososc;
  }
  
  public void setAgrososc(boolean flag) {
    this._Agrososc = flag;
  }
  
  public int getHomeX() {
    return this._homeX;
  }
  
  public void setHomeX(int i) {
    this._homeX = i;
  }
  
  public int getHomeY() {
    return this._homeY;
  }
  
  public void setHomeY(int i) {
    this._homeY = i;
  }
  
  public boolean isReSpawn() {
    return this._reSpawn;
  }
  
  public void setreSpawn(boolean flag) {
    this._reSpawn = flag;
  }
  
  public int getLightSize() {
    return this._lightSize;
  }
  
  public void setLightSize(int i) {
    this._lightSize = i;
  }
  
  public boolean isWeaponBreaked() {
    return this._weaponBreaked;
  }
  
  public void setWeaponBreaked(boolean flag) {
    this._weaponBreaked = flag;
  }
  
  public int getHiddenStatus() {
    return this._hiddenStatus;
  }
  
  public void setHiddenStatus(int i) {
    this._hiddenStatus = i;
  }
  
  public int getMovementDistance() {
    return this._movementDistance;
  }
  
  public void setMovementDistance(int i) {
    this._movementDistance = i;
  }
  
  public int getTempLawful() {
    return this._tempLawful;
  }
  
  public void setTempLawful(int i) {
    this._tempLawful = i;
  }
  
  public int calcSleepTime(int sleepTime, int type) {
    if (sleepTime <= 0)
      sleepTime = 960; 
    switch (getMoveSpeed()) {
      case 1:
        sleepTime = (int)(sleepTime - sleepTime * 0.25D);
        break;
      case 2:
        sleepTime *= 2;
        break;
    } 
    if (getBraveSpeed() == 1)
      sleepTime = (int)(sleepTime - sleepTime * 0.25D); 
    if (hasSkillEffect(167) && (type == 1 || type == 2))
      sleepTime = (int)(sleepTime + sleepTime * 0.25D); 
    return sleepTime;
  }
  
  protected boolean isAiRunning() {
    return this._aiRunning;
  }
  
  protected void setAiRunning(boolean aiRunning) {
    this._aiRunning = aiRunning;
  }
  
  public boolean destroyed() {
    return this._destroyed;
  }
  
  protected L1MobSkillUse mobSkill() {
    return this._mobSkill;
  }
  
  protected boolean isActived() {
    return this._actived;
  }
  
  protected void setActived(boolean actived) {
    this._actived = actived;
  }
  
  protected boolean isFirstAttack() {
    return this._firstAttack;
  }
  
  protected void setFirstAttack(boolean firstAttack) {
    this._firstAttack = firstAttack;
  }
  
  protected int getSleepTime() {
    return this._sleep_time;
  }
  
  public void setSleepTime(int sleep_time) {
    this._sleep_time = sleep_time;
  }
  
  protected boolean isDeathProcessing() {
    return this._deathProcessing;
  }
  
  protected void setDeathProcessing(boolean deathProcessing) {
    this._deathProcessing = deathProcessing;
  }
  
  public int drainMana(int drain) {
    if (this._drainedMana >= ConfigOther.drainedMana)
      return 0; 
    int result = Math.min(drain, getCurrentMp());
    if (this._drainedMana + result > ConfigOther.drainedMana)
      result = ConfigOther.drainedMana - this._drainedMana; 
    this._drainedMana += result;
    return result;
  }
  
  public void transform(int transformId) {
    stopHpRegeneration();
    stopMpRegeneration();
    int transformGfxId = getNpcTemplate().getTransformGfxId();
    if (transformGfxId != 0)
      broadcastPacketAll((ServerBasePacket)new S_SkillSound(getId(), transformGfxId)); 
    L1Npc npcTemplate = NpcTable.get().getTemplate(transformId);
    setting_template(npcTemplate);
    broadcastPacketAll((ServerBasePacket)new S_ChangeShape(this, getTempCharGfx()));
    Iterator<L1PcInstance> iterator = World.get().getRecognizePlayer((L1Object)this).iterator();
    while (iterator.hasNext()) {
      L1PcInstance pc = iterator.next();
      if (pc.get_showId() != get_showId())
        continue; 
      onPerceive(pc);
    } 
  }
  
  public boolean isRest() {
    return this._rest;
  }
  
  public void setRest(boolean rest) {
    this._rest = rest;
  }
  
  public boolean isResurrect() {
    return this._isResurrect;
  }
  
  public void setResurrect(boolean flag) {
    this._isResurrect = flag;
  }
  
  public synchronized void resurrect(int hp) {
    if (this._destroyed)
      return; 
    super.resurrect(hp);
    startHpRegeneration();
    startMpRegeneration();
    broadcastPacketAll((ServerBasePacket)new S_Resurrection(this, this, 0));
    L1SkillUse skill = new L1SkillUse();
    skill.handleCommands(null, 44, getId(), getX(), getY(), 0, 1, this);
    if (this._deadTimerTemp != -1)
      this._deadTimerTemp = -1; 
  }
  
  protected synchronized void startDeleteTimer(int deltime) {
    if (this._deadTimerTemp != -1)
      return; 
    this._deadTimerTemp = deltime;
  }
  
  public boolean isInMobGroup() {
    return (getMobGroupInfo() != null);
  }
  
  public L1MobGroupInfo getMobGroupInfo() {
    return this._mobGroupInfo;
  }
  
  public void setMobGroupInfo(L1MobGroupInfo m) {
    this._mobGroupInfo = m;
  }
  
  public int getMobGroupId() {
    return this._mobGroupId;
  }
  
  public void setMobGroupId(int i) {
    this._mobGroupId = i;
  }
  
  public void startChat(int chatTiming) {
    if (chatTiming == 0 && isDead())
      return; 
    if (chatTiming == 1 && !isDead())
      return; 
    if (chatTiming == 2 && isDead())
      return; 
    if (chatTiming == 3 && isDead())
      return; 
    int npcId = getNpcTemplate().get_npcId();
    L1NpcChat npcChat = null;
    switch (chatTiming) {
      case 0:
        npcChat = NpcChatTable.get().getTemplateAppearance(npcId);
        break;
      case 1:
        npcChat = NpcChatTable.get().getTemplateDead(npcId);
        break;
      case 2:
        npcChat = NpcChatTable.get().getTemplateHide(npcId);
        break;
      case 3:
        npcChat = NpcChatTable.get().getTemplateGameTime(npcId);
        break;
    } 
    if (npcChat == null)
      return; 
    Timer timer = new Timer(true);
    L1NpcChatTimer npcChatTimer = new L1NpcChatTimer(this, npcChat);
    if (!npcChat.isRepeat()) {
      timer.schedule((TimerTask)npcChatTimer, npcChat.getStartDelayTime());
    } else {
      timer.scheduleAtFixedRate((TimerTask)npcChatTimer, npcChat.getStartDelayTime(), npcChat.getRepeatInterval());
    } 
  }
  
  public int getBowActId() {
    if (this._bowActId != -1)
      return this._bowActId; 
    return getNpcTemplate().getBowActId();
  }
  
  public void setBowActId(int bowActId) {
    this._bowActId = bowActId;
  }
  
  public int get_ranged() {
    if (this._ranged != -1)
      return this._ranged; 
    return getNpcTemplate().get_ranged();
  }
  
  public void set_ranged(int ranged) {
    this._ranged = ranged;
  }
  
  public final int getSkyTime() {
    return this._skyTime;
  }
  
  public final void setSkyTime(int i) {
    this._skyTime = i;
  }
  
  public int get_quest_id() {
    return this._quest_id;
  }
  
  public void set_quest_id(int quest_id) {
    this._quest_id = quest_id;
  }
  
  public boolean isShop() {
    return this._isShop;
  }
  
  public void set_isShop(boolean isShop) {
    if (this instanceof L1DeInstance) {
      L1DeInstance de = (L1DeInstance)this;
      de.setShopChat(DeShopChatTable.get().getChat(), DeShopChatTable.get().getChat());
    } 
    this._isShop = isShop;
  }
  
  public int get_spawnTime() {
    return this._spawnTime;
  }
  
  public boolean is_spawnTime() {
    return this._isspawnTime;
  }
  
  public void set_spawnTime(int spawnTime) {
    this._spawnTime = spawnTime;
    this._isspawnTime = true;
  }
  
  public boolean isremovearmor() {
    return this._isremovearmor;
  }
  
  public void set_removearmor(boolean isremovearmor) {
    this._isremovearmor = isremovearmor;
  }
  
  public int get_deadTimerTemp() {
    return this._deadTimerTemp;
  }
  
  public void set_deadTimerTemp(int time) {
    this._deadTimerTemp = time;
  }
  
  public int get_stop_time() {
    return this._stop_time;
  }
  
  public void set_stop_time(int time) {
    this._stop_time = time;
  }
  
  public int get_work_time() {
    return this._work_time;
  }
  
  public void set_work_time(int time) {
    this._work_time = time;
  }
  
  public long getShellsDamageTime() {
    return this._shells_damag_time;
  }
  
  public void setShellsDamageTime(long i) {
    this._shells_damag_time = i;
  }
  
  public long getShellsSilenceTime() {
    return this._shells_silence_time;
  }
  
  public void setShellsSilenceTime(long i) {
    this._shells_silence_time = i;
  }
  
  public String get_craftkey() {
    return this._craftkey;
  }
  
  public void set_craftkey(String craftkey) {
    this._craftkey = craftkey;
  }
  
  public class DelItemTime {
    public int _del_item_time = 0;
  }
}
